perm filename LUMEN[901,BGB] blob
sn#129632 filedate 1974-11-12 generic text, type T, neo UTF8
00100 TITLE LUMEN
00150 OPDEF OUTSTG [XWD 51140,0]
00200
00300 LUMEN:
00400
00500 ;CLEAR RASTER TO DARKNESS.
00600 MOVE [BYTE (4)16,16,16,16,16,16,16,16,16]
00650 MOVEM RASTER
00700 MOVE 1,[XWD RASTER,RASTER+1]
00800 BLT 1,RASTER+15624
00900
01000 JSR PASS3
01100 JSR OCCULT
01200
01300 INIT 5,17
01400 SIXBIT/DSK/
01500 0
01600 HALT
01700 ENTER 5,[SIXBIT/VIEW/ ↔ SIXBIT/DAT/ ↔ 0 ↔ 0]
01800 HALT
01900 OUTPUT 5,[XWD -15633,RASTER-13 ↔ 0 ↔ 0]
02000 CLOSE 5,
02100
02200 HALT
02300
02400 0↔7↔0↔4↔374↔34↔0↔373↔0↔373↔15620
02500
02600 RASTER:
02700
02800 BLOCK 15630
02900
00100 PASS3: 0
00200 BEGIN PASS3
00300 SETZM NLEAST# ;COUNT OF TRIANGLES
00500 ;ACCUMULATORS
00600 A←←XY1←←KA←←0
00700 B←←XY2←←AC0←←LA←←1
00800 C←←XY3←←AC1←←2
00900 AA←←I1←←Z12←←LO←←LB←←KB←←3
01000 BB←←I2←←Z3I←←HI←←4
01100 CC←←I3←←C12←←MID←←5
01200 X1←←AB1←←6
01300 X2←←AB2←←7
01400 X3←←AB3←←10
01500 Y1←←AB←←11
01600 Y2←←CC3←←12
01700 Y3←←13
01800 Z1←←Z←←14
01900 Z2←←TRI←←15
02000 Z3←←LC←←16
02100 ZT←←QB←←II←←KK←←KC←←17
02200 KPLANE←1
00100 LOOP: MOVE QB,NLEAST ;DONE YET
00200 CAML QB,NUMTRI
00300 JRST @PASS3
00400 ;BLIT TRIANGLE BLOCK INTO AC'S
00500 IMULI QB,5
00600 ADDI QB,INPUT3
00700 MOVSS QB
00800 BLT QB,4
00900 ;UNPACK TRIANGLE BLOCK
01000 FOR @$ I←1,3 {
01100 HLRE X$I,XY$I
01200 HRRE Y$I,XY$I ⎇
01300 HLRE Z1,Z12
01400 HRRE Z2,Z12
01500 HLRE Z3,Z3I
01600 HRRZ II,Z3I
01700 P3B:
01800 TRNE II,4 ↔ SKIPA I1,[1] ↔ SETZ I1,
01900 TRNE II,2 ↔ SKIPA I2,[1] ↔ SETZ I2,
02000 TRNE II,1 ↔ SKIPA I3,[1] ↔ SETZ I3,
02100 P3A:
02200 ;ORDER Z1 LEAST, Z3 MOST.
02300 DEFINE SWAP $ (N,M) {
02400 CAMG Z$N,Z$M
02500 JRST .+5
02600 EXCH X$N,X$M
02700 EXCH Y$N,Y$M
02800 EXCH Z$N,Z$M
02900 EXCH I$N,I$M ⎇
03000 SWAP 1,2
03100 SWAP 2,3
03200 SWAP 1,2
03300
03400 MOVE II,I1 ;RE-PACK I-BITS
03500 LSH II,1
03600 IOR II,I2
03700 LSH II,1
03800 IOR II,I3
03900
04000 EXCH II,[KPLANE]
00100 ;CALCULATE COEFFICIENTS OF THE PLANE OF THE TRIANGLE BY KRAMER'S RULE.
00200 DEFINE DET2B2 (A00,B11,B12,B21,B22) {
00300 MOVE B,B11
00400 MOVE C,B12
00500 IMUL B,B22
00600 IMUL C,B21
00700 SUB B,C
00800 IMUL B,A00 ⎇
00900
01000 DEFINE DETERM (A11,A12,A13,A21,A22,A23,A31,A32,A33) {
01100 DET2B2 A11,A22,A23,A32,A33
01200 MOVE A,B
01300 DET2B2 A12,A21,A23,A31,A33
01400 SUB A,B
01500 DET2B2 A13,A21,A22,A31,A32
01600 ADD A,B ⎇
01700
01800 DETERM KK,Y1,Z1,KK,Y2,Z2,KK,Y3,Z3
01900 MOVE AA,A
02000 DETERM X1,KK,Z1,X2,KK,Z2,X3,KK,Z3
02100 MOVE BB,A
02200 DETERM X1,Y1,KK,X2,Y2,KK,X3,Y3,KK
02300 MOVE CC,A
02400 DETERM X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3
02500 MOVEM A,KSAVE#
02600 BRK:
02700 ;HALFWORD OVERFLOW.
02800 DEFINE HALFOV (W,WW){
02900 MOVM W,WW
03000 CAIGE W,400000
03100 JRST .+10
03200 MOVE W,KSAVE ;OVERFLOW
03300 ASH W,-1
03400 MOVEM W,KSAVE
03500 ASH AA,-1
03600 ASH BB,-1
03700 ASH CC,-1
03800 JRST .-11
03900 ⎇
04000 HALFOV A,AA
04100 HALFOV B,BB
04200 HALFOV C,CC
04300 P3C:
04400 ;PACK PLANE COEFFICIENTS
04500 HRL BB,AA
04600 HRLS CC
04700 EXCH KK,[KPLANE] ;COL-1
00100 ;CALCULATE LINE COEFFICIENTS
00200 DEFINE LINCOE (X1,X2,Y1,Y2,TA,TB,TC,X3,Y3) {
00300 MOVE TA,Y2
00400 MOVE TB,X1
00500 SUB TA,Y1 ;(Y2-Y1)=a
00600 SUB TB,X2 ;(X1-X2)=b
00700 HRL TC,TA
00800 HRR TC,TB
00900 IMUL TA,X1 ; A*x1
01000 IMUL TB,Y1 ; B*y1
01100 ADD TA,TB
01200 MOVNS TA
01300 MOVM TB,TA
01400 CAIGE TB,400000
01500 JRST .+6
01600 HLRE TA,TC ;HALFWORD OVERFLOW CURE
01700 HRRE TB,TC
01800 ASH TA,-1
01900 ASH TB,-1
02000 JRST .-15 ;JUMP TO THE "HRL" ABOVE.
02100 ;TA c
02200 ;TB free
02300 ;TC a,,b
02400 ;observe qqq sign convention - odd vertex positive.
02500 HLRE TB,TC
02600 IMUL TB,X3
02700 MOVEM TB,AC20
02800 HRRE TB,TC
02900 IMUL TB,Y3
03000 ADD TB,AC20
03100 ADD TB,TA
03200 JUMPGE TB,.+7
03300 MOVNS TA ;FLIP SIGN OF LINE COEFFICIENTS.
03400 HLRE TB,TC
03500 HRRE TC,TC
03600 MOVNS TB
03700 MOVNS TC
03800 HRL TC,TB
03900 ⎇
04000 HRL QB,Z3
04100 LINCOE X1,X2,Y1,Y2,A,B,C,X3,Y3
04200 LINCOE X1,X3,Y1,Y3,LA,LB,LC,X2,Y2 ;COL-2
04300 HRR CC,A ;PACK c3
04400 MOVEM KC,SAVKC#
04500 LINCOE X2,X3,Y2,Y3,KA,KB,KC,X1,Y1 ;COL-4
04600 HRL Y1,X1
04700 MOVE X1,KC
04800 MOVE KC,SAVKC
00100 P3D:
00200 ;PACK EVERYTHING INTO YOUR OLD KIT BAG AND SMILE SMILE SMILE
00300 ; WOULD YOU BELIEVE A LONG TRIANGLE BLOCK
00400 HRL Y2,X2
00500 HRL Y3,X3
00600 MOVE AB2,LC
00700 MOVE AB3,C
00800 MOVE 2,13
00900 HRL 1,0
01000 HRL 3,14
01100 HRR 3,15
01200 MOVE 0,11
01300 EXCH 1,12
01400 EXCH 5,12
01500 MOVE 11,4
01600 MOVE 4,17
01700 MOVE 13,KSAVE
01800
01900 ;PATCH FOR INTENSITY.
02000 PATCH1: MOVEM 14,SAV14# ↔ MOVEM 15,SAV15#
02100 HLRE 14,11 ↔ ASH 14,-2
02200 HRRE 15,11 ↔ ASH 15,-2
02300 IMUL 14,14
02400 IMUL 15,15
02500 ADD 14,15
02600 HLRE 15,12 ↔ ASH 15,-2
02700 IMUL 15,15
02800 ADD 14,15
02900
03000 MOVEM 14,DENOM#
03100 MOVEI 14,20
03200 MUL 14,15
03300 DIV 14,DENOM
03400 MOVNS 14
03500 ADDI 14,20
03600 PATCH2:
03700
03800 ;BLIT BLOCK INTO LONG BLOCK TABLE.
03900 MOVE 17,NLEAST
04000 IMULI 17,15
04100 ADDI 17,TRIBLKS
04200 MOVE 16,17
04300 ADDI 16,14
04400 BLT 17,@16
04500 MOVE 14,SAV14
04600 MOVE 15,SAV15
00100 P3E:
00200 ;PUT TRIANGLE BLOCK POINTER INTO THE TRIANGLE TABLE
00300 ;IN ORDER ON MINIMUM DEPTH.
00400 HRL ZT,Z
00500 MOVE TRI,NUMTRI
00600 SKIPN LO,NLEAST
00700 JRST [AOS NLEAST ;FIRST TIME ONLY.
00800 MOVEM ZT,TRITAB-1(TRI)
00900 JRST LOOP]
01000 SETZ HI,
01100 PUT1: MOVE MID,LO ;MID:=(LO+HI+1)/2
01200 ADD MID,HI
01300 AOS MID
01400 ASH MID,-1
01500 MOVE LC,TRI ;FETCH Z(MID)
01600 SUB LC,MID
01700 HLRE A,TRITAB(LC)
01800 CAML Z,A
01900 JRST [CAMN LO,MID
02000 JRST PUT2
02100 CAMN HI,MID
02200 JRST PUT2
02300 MOVE LO,MID
02400 JRST PUT1]
02500 CAMN LO,MID
02600 JRST [AOS MID
02700 JRST PUT2]
02800 CAMN HI,LO
02900 JRST [AOS MID
03000 JRST PUT2]
03100 MOVE HI,MID
03200 JRST PUT1
03300 ;MOVE THE LOWER PART OF THE TRIANGLE TABLE,
03400 ;BETWEEN NLEAST AND MID,
03500 ;DOWN CORE BY ONE WORD.
03600 PUT2: CAMLE MID,NLEAST
03700 JRST PUT3
03800 MOVEI AC0,TRITAB
03900 ADD AC0,TRI
04000 MOVE AC1,AC0
04100 SUB AC0,NLEAST
04200 HRLS AC0
04300 SOS AC0
04400 SUB AC1,MID
04500 SOS AC1
04600 BLT AC0,@AC1
04700 PUT3: AOS NLEAST
04800 SUB TRI,MID
04900 MOVEM ZT,TRITAB(TRI)
05000 JRST LOOP
05100 AC20: 0
05200 BEND
00100 OCCULT: 0
00200 BEGIN OCCULT
00300 ;USE AND ABUSE OF ACCUMULATORS
00400 AC0←←0
00500 AC1←←1
00600 XM←←0
00700 YM←←1
00800
00900 XL←2 ;The window.
01000 XH←3
01100 YL←4
01200 YH←5
01300
01400 X1←AA←←6 ;The triangle.
01500 X2←BB←←7
01600 X3←CC←←10
01700
01800 Y1←MINZ←←11
01900 Y2←MAXZ←←12
02000 Y3←13
02100
02200 AB←←14 ;Plane coefficients.
02300 C←←15
02400
02500 T←16
02600 TT←17
02700
02800 XO←←14
02900 YO←←15
03000 PB←←17
03100
03200 ODD←←13
03300 NEW←←14
03400 OLD←←15
03500
03600 XY←←11
03700 X←←6
03800 Y←←7
03900 Z←←10
04000 EPTR←←14
04100 BPTR←←15
04200 CTB←←17
00100 ;O.O.R. - Occult Object Remover.
00300 hrl TT,numtri ;Triangle pointer.
00400 movns TT ;This op covertly Subtracts one from left half.
00500 hrri TT,tritab-1
00600 movem TT,triptr#
00700
00800 movni XL,1000 ;first window
00900 movei XH,1000
01000 movni YL,1000
01100 movei YH,1000
01200 FOR W IN (PENOLD,PENNEW,SUR,SUR3,APEN,ASUR,ASUR3){
01300 SETZM W}
01400 movei 377777
01500 movem ZH#
01600 movei sqrpdl+1
01700 movem sqrpdl
01800 movei outpdl+1
01900 movem outpdl
02000 jrst .V
02100 ;Occult Window Loop.
02200 OWLOOP: sos 1,sqrpdl
02300 caig 1,sqrpdl+1
02400 jrst @occult ;no more windows.
02500
02600 hlre XL,-5(1) ;new window
02700 hrre XH,-5(1)
02800 hlre YL,-4(1)
02900 hrre YH,-4(1)
03000
03100 hrre -3(1) ;back limit.
03200 movem ZH
03300
03400 move (1) ;triangle pointer
03500 movem triptr
03600
03700 move -2(1) ;ancesters
03800 movem apen#
03900 move -1(1)
04000 movem asur#
04100 hlrz -3(1)
04200 movem asur3#
04300
04400 setzm pennew# ;descendants
04500 setzm penold#
04600 setzm sur#
04700 setzm sur3#
04800
04900 subi 1,5
05000 movem 1,sqrpdl
05100 jrst .V
00100 ;Virgin - scan for first triangle.
00200 .V: jsr pns
00300 jrst [ movem minz,penzlo#
00400 movem maxz,penzhi#
00500 movem T,pennew
00600 jrst %PP]
00700 jrst owloop
00800 movem minz,surzlo#
00900 movem maxz,surzhi#
01000 hrlzm T,sur
01100 ;One surrounder.
01200 .S: jsr pns
01300 jrst [ caml minz,surzhi
01400 jrst .S ;B - penetrator is behind surrounder.
01500 movem T,pennew
01600 caml maxz,surzlo
01700 jrst %PS ;C - penetrator and surrounder conflict.
01800 movem minz,penzlo ;F - penetrator is in Front of surrounder
01900 movem maxz,penzhi
02000 jrst %PP]
02100 jrst alpha ;DISPLAY a surrounder.
02200 caml minz,surzhi
02300 jrst .S ;B - new surrounder is behind old surrounder.
02400 caml maxz,surzlo
02500 jrst [ movem minz,zlo# ;C - surrounders conflict.
02600 movem maxz,zhi#
02700 hrrm T,sur
02800 jrst %PP]
02900 movem minz,surzlo ;F - new surrounder is in front of old surrounder
03000 movem maxz,surzhi
03100 hrlm T,sur
03200 jrst .S
03300
00100 SQRPDL: .+1 ;WINDOW SQUARE IN CORE PUSHDOWN LIST
00200 0 ; XL XH
00300 0 ; YL YH
00400 0 ;sur3,,ZH
00500 0 ; PEN1,,PEN2
00600 0 ; SUR1,,SUR2
00700 0 ; TRIPTR
00800 BITS←←=10 ;NUMBER OF BITS OF DISPLAY RASTER.
00900 BLOCK (BITS*3+1)*6
01000 SQREND:
00100 ;DISPLAY OUTPUT SURROUNDER.
00200 ALPHA:
00300 ADDI XL,1000
00400 ADDI XH,1000
00500 SUBI YL,1000
00600 SUBI YH,1000
00700 MOVMS YL
00800 MOVMS YH
00900 IMULI XL,374
01000 IMULI XH,374
01100 IMULI YL,374
01200 IMULI YH,374
01300 ASH XL,-12
01400 ASH XH,-12
01500 ASH YL,-12
01600 ASH YH,-12
01700 SUB YL,YH
01800 SUB XH,XL
01900
02000 IMULI YH,34
02100 MOVE 10,XL
02200 IDIVI 10,11
02300 ADD YH,10
02400 IMUL 11,[-4]
02500 ADDI 11,40
02600 ROT 11,-6
02700 ADD 11,[POINT 4,RASTER(10),35]
02800
02850 HLRZ T,SUR
02900 MOVE 6,14(T)
03000
03100 MOVE 10,YH
03200 MOVE 7,YL
03300 DPB 6,11
03400 ADDI 10,34
03500 SOJGE 7,.-2
03600 IBP 11
03700 SOJGE XH,.-6
03800
03900 JRST OWLOOP
00100 ;OCCUPATION VOLUME
00200
00300 ; Compute the occupation volume of the Triangle pointed
00400 ;to by T for the window XL XH YL YH, find the minimum and maximum Z for all
00500 ;corners of the window without exceeding the triangle's total volume z1
00600 ;minimum to z3 maximum; if you are worth anything you have by now realized
00700 ;that this will yield too large a volume for numerous penetrator cases
00800 ;where the vertices aren't in the window and the corners aren't in the triangle
00900 ;but it doesn't matter and will all come out correctly further along.
01000
01100 OCCVOL: 0
01200 HLRE AA,11(T) ;PICKUP COEFFICIENTS OF TRIANGLE'S PLANE.
01300 HRRE BB,11(T)
01400 HLRE CC,12(T)
01500 SETCM T
01600 TLNE (5B2) ;IF EXTREME VERTICES ARE WITHIN...
01700 JRST .+4
01800 HLRE MINZ,3(T) ;THEN OCCUPATION VOLUME IS OBVIOUS.
01900 HLRE MAXZ,4(T)
02000 JRST @OCCVOL
02100 HRLZI MAXZ,400000 ;Z1
02200 SETCAM MAXZ,MINZ ;Z3
02300 ;calculte z-depth of window corners in the plane of the triangle.
02400 FOR I←0,3
02500 {
02600 MOVE AC0,13(T)
02700 MOVE AC1,XL+(I∧1)
02800 IMUL AC1,AA
02900 SUB AC0,AC1
03000 MOVE AC1,YL+((I∧2)⊗-1)
03100 IMUL AC1,BB
03200 SUB AC0,AC1
03300 IDIV AC0,CC
03400 CAMGE AC0,MINZ
03500 MOVE MINZ,AC0
03600 CAMLE AC0,MAXZ
03700 MOVE MAXZ,AC0
03800 ⎇
03900 ;Clip window's projected volume to the extreme volume of the triangle.
04000 HLRE AC0,3(T)
04100 HLRE AC1,4(T)
04200 CAMLE AC0,MINZ
04300 MOVE MINZ,AC0
04400 CAMGE AC1,MAXZ
04500 MOVE MAXZ,AC1
04600
04700
04800 JRST @OCCVOL
00100 ;P.O.S. - Penetrator, Outsider, Surrounder.
00200 pos:
00300 comment/ POS determines the relationship between a triangle and a window
00400 and skips respectively. For penetrators it always calculates
00500 vertex-within-bits, For Pen & Surs it always calculates volume.
00600 Accumulators IN: XL,XH,YL,YH, & T(right half).
00700 /
00800
00900 ;GET TRIANGLE'S COORDINATES INTO ACCUMULATORS.
01000 define gettac {
01100 hlre x1,0(T)
01200 hlre x2,1(T)
01300 hlre x3,2(T)
01400 hrre y1,0(T)
01500 hrre y2,1(T)
01600 hrre y3,2(T)
01700 }
01800 gettac
01900
02000 ;If all the corners of the triangle are to one side of the window,
02100 ; then the triangle is Outside.
02200
02300 define Outside $ (M,N,P,HL) {
02400 CAM$M P$HL,P$1 ↔ JRST .+5
02500 CAM$M P$HL,P$2 ↔ JRST .+3
02600 CAM$N P$HL,P$3 ↔ JRST pnsout
02700 }
02800 Outside LE,g,X,H
02900 Outside LE,g,Y,H
03000 Outside GE,l,X,L
03100 Outside GE,l,Y,L
03200
03300
03400 ;If any vertex of the Triangle is within the window,
03500 ; then it is a penetrator.
03600 ;EDGE CASES.
03700 For @$ N←1,3 {
03800 caml X$N,XH ↔JRST[CAMN X$N,XH ↔ IOR T,[1⊗(=21-N)]↔ jrst .+7]
03900 caml XL,X$N ↔JRST[CAMN XL,X$N ↔ IOR T,[1⊗(=21-N)]↔ jrst .+5]
04000 caml Y$N,YH ↔JRST[CAMN Y$N,YH ↔ IOR T,[1⊗(=21-N)]↔ jrst .+3]
04100 camg YL,Y$N ↔JRST[CAMN YL,Y$N↔JRST[IOR T,[1⊗(=21-N)]↔JRST .+1]↔ ior T,[1⊗(=36-N)]↔JRST .+1]
04200 }
04300
04400 tlnn T,(7b2)
04500 jrst .+3
04600 jsr occvol ;Found a Penetrator.
04700 jrst @pns
04800
04900
00100 ;SURROUNDS
00200
00300 comment/ For each edge of the triangle, if for every corner of
00400 the window QQQ is the same sign then that edge does not pass
00500 thru the window. The odd vertex is in the opposite half plane
00600 from the window if the QQQs are all negative - which is
00700 equivalent to saying that the triangle is outside of the window.
00800 /
00900 jsr calq
01000 jrst pnsout ;OUTSIDE.
01100 tlne T,77770
01200 jrst [jsr occvol ↔ jrst @pns] ;PENETRATOR.
01300 jsr occvol ↔ camge maxz,zh ↔ movem maxz,zh ;lower ZH - SURROUNDER.
01400 aos pns
01500 aos pns
01600 jrst @pns
01700
01800 ;P.N.S - Penetrator, Nil list, Surrounder.
01900 pns: 0
02000 ;Get pointer to next triangle, if list is empty or triangle is
02100 ;beyond the back limit then take the NIL exit.
02200 pnsout: skipe T,asur ;Check for ancestors.
02300 jrst [hlrzs T ;left SUR 1.
02400 jumpe T,[exch T,asur ;right SUR 2
02500 jrst pnssur]
02600 hrrzs asur
02700 jrst pnssur]
02800 skipe T,asur3
02900 jrst [setzm asur3
03000 jrst pnssur]
03100 skipe T,apen
03200 jrst [hlrzs T ;left PEN 1
03300 jumpe T,[exch T,apen ;right pen 2
03400 jrst pos]
03500 hrrzs apen
03600 jrst pos]
03700 move TT,Triptr
03800 beyond: aobjp TT,[aos pns
03900 jrst @pns]
04000 movem TT,Triptr
04100 hrrz T,(TT)
04200 hlre (TT)
04300 caml zh
04400 jrst @beyond ;beyond ZH.
04500 jrst pos
04600 pnssur: jsr occvol ↔ camge maxz,zh ↔ movem maxz,zh ;lower Zh.
04700 aos pns ;surrounds
04800 aos pns
04900 jrst @pns
00100 ;Calculate QQQ-bits, skip if not outside.
00200 calq: 0
00300 movsi PB,40000 ;Select QQQ bit.
00400 define qqq (corner) {
00500 hlre ac1,AB
00600 hrre ac0,AB
00700 imul ac1,XL+ (corner ∧ 1)
00800 imul ac0,YL+((corner ∧ 2)⊗-1)
00900 add ac1,ac0
01000 add ac1,C
01100 }
01200
01300 for edge ← 1,3 {
01400 move AB,5+edge(T) ;Get line Coefficients
01500 IFE (edge-1),<hlre C,5(T)>
01600 IFE (edge-2),<hrre C,5(T)>
01700 IFE (edge-3),<hrre C,12(T)>
01800 for corner ← 0,3 {
01900 qqq corner
02000 skipge ac1 ;Q sign convention - odd vertex positive.
02100 ior T,PB
02200 rot PB,-1
02300 }
02400
02500 setcm ac1,T
02600 tlnn ac1,(17⊗(=33-edge*4))
02700 jrst @calq ;Triangle outside of window.
02800 }
02900 aos calq
03000 jrst @calq
00100 ;Convert QQQ-bits into Pen-bits.
00200 CONQQQ: 0
00300 gettac
00400 ;Accumulators IN: XL,XH,YL,YH (the window)
00500 ; X1,X2,X3,Y1,Y2,Y3 (the triangle)
00600 ; T (the triangle pointer)
00700 ;Accumulators clobbered 0,1,14,15.
00800 tlne T,(7B2) ;If a vertex is within, then we must calQ.
00900 jrst [ jsr calq
01000 jfcl
01100 jrst .+1]
01200 for @$ edge←1,3 {
01300 BP←←2+edge*4 ;Bit pointer for testing.
01400 V ←←((7-edge)*edge)/2 ;non-edge select bits.
01500 setcm T ;If both vertices within,
01600 tlne (V ⊗=33)
01700 jrst .+3
01800 tlz T,(17⊗(=35-BP)) ;Then zero NSEW byte.
01900 jrst conq$edge
02000 ;Convert 4-bit byte by table lookup.
02100 ldb ac1,[point 4,T,BP]
02200 move [ 0 ↔ 12 ↔ 11 ↔ 3 ↔ 6 ↔ 14 ↔ 0 ↔ 5
02300 5 ↔ 0 ↔ 14 ↔ 6 ↔ 3 ↔ 11 ↔ 12 ↔ 0](ac1)
02400 tlne T,(V ⊗ =33) ;If both vertices without
02500 jrst .+6
02600 dpb [point 4,T,BP]
02700 movei 1,V
02800 jsr skpcruz
02900 tlz T,(17⊗(=35-bp)) ;no crossings - zip NSEW.
03000 jrst conq$edge ;Then we are done, Else:
03100 ;Find vertex that is outside the window.
03200 selec1←←(IFE(1-edge),<1+>0) ;1,0,0 - first select.
03300 selec2←←(IFE(3-edge),<1+>1) ;2,2,1 - second select.
03400 tlne T,(1⊗(=35-selec1))
03500 ;First selected bit is inside, hence second is outside.
03600 jrst [
03700 move XO,X1+selec2
03800 move YO,Y1+selec2
03900 jrst .+3]
04000
04100 ;First selected bit is outside.
04200 move XO,X1+selec1
04300 move YO,y1+selec1
04400
04500 ;Call one-crossing routine & you are done.
04600 jsr cross
04700 dpb [point 4,T,BP]
04800 conq$edge:
04900 }
05000 jrst @conqqq
00100 CROSS: 0
00200
00300 comment / The following tortured logic converts qqq-bits (which
00400 tell which half plane the window corners are in with respect
00500 to the lines determined by the triangle) into pen-bits (which
00600 tell which sides of the window: North, South, East or West, each
00700 triangle edge segment crosses).
00800
00900 Accumulators: XO,YO & AC1.
01000 /
01100
01200 ;If the 2-bit is on
01300 trne 2 ↔ jrst [
01400 ;then
01500
01600 ;If XO ≥ XH
01700 caml XO,XH ↔ jrst [
01800 ;Then 2-mask
01900 andi 2
02000 jrst @cross ]
02100 ;Else 15-mask
02200 andi 15
02300 jrst @cross ]
02400
02500 ;Else
02600 ;If 10-bit is on
02700 trne 10 ↔ jrst [
02800 ;Then If YO ≥ YH
02900 caml YO,YH ↔ jrst [
03000 ;Then 10-mask
03100 andi 10
03200 jrst @cross]
03300 ;Else 5-mask
03400 andi 5
03500 jrst @cross]
03600 ;Else If XL > XO
03700 camle XL,XO ↔ jrst [
03800 ;Then 1-mask
03900 andi 1
04000 jrst @cross]
04100 ;Else 4-mask
04200 andi 4
04300 jrst @cross
04400
04500 ;SKIPs if outsiders' edge crosses window. No crossings - no Skippings.
04600 skpcruz: 0
04700 setz
04800 for @$ i←1,3 {
04900 camle x$i,XL
05000 tro 1⊗(3-i)
05100 camle y$i,yl
05200 tro 1⊗(22-i)
05300 camle xh,x$i
05400 tlo 1⊗(3-i)
05500 camle yh,y$i
05600 tlo 1⊗(22-i)
05700 }
05800 tdnn 1 ↔ jrst @skpcruz
05900 tsnn 1 ↔ jrst @skpcruz
06000 rot 3
06100 tdnn 1 ↔ jrst @skpcruz
06200 tsnn 1 ↔ jrst @skpcruz
06300 aos skpcruz
06400 jrst @skpcruz
00100 ;Save Father's surrounders & penetrators and EXIT.
00200 %SSS: ↔ %PSS: ↔ %PPS: ↔ %PP: ↔ %PS:
00300 move 11,ZH
00400 hrl 11,sur3
00500 move 12,penold
00600 hrl 12,pennew
00700 move 13,sur
00800 move 14,triptr
00900 ;Split up the window, Recursion Exit.
01000 rexit: move XM,XL
01100 move YM,YL
01200 add XM,XH
01300 add YM,YH
01400 ash XM,-1
01500 ash YM,-1
01600 ;RESOLUTION DISPLAY OUTPUT.
01700 MOVE 6,XH ↔ SUB 6,XL ↔ CAIG 6,1 ↔ JRST OWLOOP
03700
03800 move 6,sqrpdl ;setup blit pointer
03900 hrli 6,7
04000 move 15,6
04100 move 16,6
04200 move 17,6
04300 addi 16,6
04400 addi 17,14
04500 move 7,XH ;lower-right-window
04600 move 10,YM
04700 hrl 7,XM
04800 hrl 10,YL
04900 blt 15,5(6)
05000 movss 7 ;lower-left-window
05100 hrl 7,XL
05200 blt 16,13(6)
05300 movss 10 ;upper-left-window
05400 hrr 10,YH
05500 blt 17,21(6)
05600 addi 6,22
05700 HRRZM 6,sqrpdl ;update pdl pointer.
05800 ;initialize OWL loop for upper-right window.
05900 move XL,XM
06000 move YL,YM
06100 movem 12,apen ;anscestors.
06200 movem 13,asur
06300 hlrzm 11,asur3
06400 setzm penold ;descendants.
06500 setzm pennew
06600 setzm sur
06700 setzm sur3
06800 jrst .V
06900 BEND
00100 NUMTRI: 20
00200 TRIBLKS: 0
00300 BLOCK 400
00400 TRITAB: 0
00500 BLOCK 40
00600 INPUT3:
00700 DEFINE TRIANG (X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,N)
00800 {
00900 XWD X1,Y1
01000 XWD X2,Y2
01100 XWD X3,Y3
01200 XWD Z1,Z2
01300 XWD Z3,N
01400 ⎇
01500
01600 DEFINE QUAD (X1,Y1,X2,Y2,Z12,X3,Y3,X4,Y4,Z34)
01700 {
01800 TRIANG X1,Y1,Z12,X2,Y2,Z12,X3,Y3,Z34,5
01900 TRIANG X1,Y1,Z12,X3,Y3,Z34,X4,Y4,Z34,6
02000 ⎇
02100
02200 QUAD -500,-700,-500,-200, 200, 440,-200, 440,-700,200
02300 QUAD -440,-100,-440, 200, 600, 300, -40,300,-600, 100
02400 QUAD 0,100,0,500,100,440,500,440,100,100
02500 QUAD -440,400,-440,700,600,-240,700,-240,400,600
02600 QUAD 0,500,440,500,100,-240,700,-440,700,600
02700 QUAD 0,100,440,100,100,-240,400,-440,400,600
02800 QUAD 440,100,440,500,100,-240,700,-240,400,600
02900 QUAD 0,100,0,500,100,-440,700,-440,400,600
03000
03100 FFLAG: -1 ;FRAME FLAG
03200 OUTPDL: .+3
03300
03400 INPUT5: XWD 1200,INPUT3
03500 XWD -500,-500
03600 BLOCK 14000
03700 ENDPDL: 0 ↔ 0 ↔ 0 ↔ 0
03800 INPUT6: 0
03900 BLOCK 40000
04000 END6: 0 ↔ 0 ↔ 0 ↔ 0
04100 END LUMEN